package com.heo.coder.packet.base;

import java.util.Date;

import com.heo.util.ByteHelper;

public abstract class BasePacket {

	public static final int START_MARKER_LENGTH = 1;// 标识位长度
	public static final String START_MARKER_LENGTH_CODE = "7E";// 标识位内容
	public static final int END_MARKER_LENGTH = 1;// 标识位长度
	public static final String END_MARKER_LENGTH_CODE = "7E";// 标识位内容
	public static final int CHECK_LENGTH = 1;

	public static final int HEAD_LENGTH = 12;// 消息头长度

	public static final String REPLACE_7D01 = "7D01";// 替换内容
	public static final String REPLACE_7D = "7D";// 替换内容
	public static final String REPLACE_7D02 = "7D02";// 替换内容
	public static final String REPLACE_7E = "7E";// 替换内容

	// 消息头
	protected String commandId = ""; // 消息 ID 4位
	protected String reserve = ""; // 预留1位 0
	protected String subcontract = ""; // 是否分包1位 0不分包
	protected String rsa = ""; // 加密1位 0不加密
	protected int bodyLength = 0; // 消息体长度 0000 0000 0000 0110 6
	protected String imei = ""; // 终端imel号 6位12字节 16进制
	protected String sequenceId = ""; // 流水号 4位 8字节

	public String head = "";
	
	public String body = null; // 具体数据 16进制数据
	protected String check = ""; // 校验位 长度1 2字节 校验码指从消息头开始，同后一字节异或，直到效验码前一个字节，占用一个字节

	protected Date createTime = new Date();


	public int getTotleLength() {
		return START_MARKER_LENGTH + HEAD_LENGTH + bodyLength + CHECK_LENGTH + END_MARKER_LENGTH;
	}

	/**
	 * 根据数据包构造对象
	 */
	public BasePacket(String commandId, String reserve, String subcontract, String rsa, int bodyLength, String imei,
			String sequenceId, String body, String check) throws Exception {
		this.commandId = commandId;
		this.reserve = reserve;
		this.subcontract = subcontract;
		this.rsa = rsa;
		this.bodyLength = bodyLength;
		this.imei = imei;
		this.sequenceId = sequenceId;
		this.body = body;
		this.check = check;
	}

	public abstract String getPacketBody();

	/**
	 * 获得整个数据包
	 * 
	 * @return
	 */
	public byte[] getPacket() {
		return ByteHelper.margeByte(
				ByteHelper.hexStringToBytes(START_MARKER_LENGTH_CODE), 
				ByteHelper.hexStringToBytes(commandId),
				ByteHelper.hexStringToBytes(head),  
				ByteHelper.hexStringToBytes(imei), 
				ByteHelper.hexStringToBytes(sequenceId), 
				ByteHelper.hexStringToBytes(body), 
				ByteHelper.hexStringToBytes(check),
				ByteHelper.hexStringToBytes(END_MARKER_LENGTH_CODE));
	}

	public String getCommandId() {
		return commandId;
	}

	public void setCommandId(String commandId) {
		this.commandId = commandId;
	}

	public String getReserve() {
		return reserve;
	}

	public void setReserve(String reserve) {
		this.reserve = reserve;
	}

	public String getRsa() {
		return rsa;
	}

	public void setRsa(String rsa) {
		this.rsa = rsa;
	}

	public int getBodyLength() {
		return bodyLength;
	}

	public void setBodyLength(int bodyLength) {
		this.bodyLength = bodyLength;
	}

	public String getImei() {
		return imei;
	}

	public void setImei(String imei) {
		this.imei = imei;
	}

	public String getSequenceId() {
		return sequenceId;
	}

	public void setSequenceId(String sequenceId) {
		this.sequenceId = sequenceId;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}

	public String getCheck() {
		return check;
	}

	public void setCheck(String check) {
		this.check = check;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getSubcontract() {
		return subcontract;
	}

	public void setSubcontract(String subcontract) {
		this.subcontract = subcontract;
	}

	public String getHead() {
		return head;
	}

	public void setHead(String head) {
		this.head = head;
	}

}
